﻿Public Class JSON
    ''' <summary>
    ''' 如果输入是JSON允许的值，则返回该输入；否则抛出。
    ''' </summary>
    ''' <param name="d"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function checkDouble(ByVal d As Double) As Double
        If Double.IsInfinity(d) Or Double.IsNaN(d) Then
            Throw New Exception("Forbidden numeric value: " + d)
        End If
        Return d
    End Function
    ''' <summary>
    ''' 转为布尔型数据
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toBoolean(ByVal value As Object) As Boolean
        If value.GetType.Equals(GetType(Boolean)) Then
            Return value
        ElseIf value.GetType.Equals(GetType(String)) Then
            Dim stringValue As String = value
            If stringValue.ToLower.Equals("true") Or stringValue.ToLower.Equals("yes") Or stringValue.ToLower.Equals("on") Then
                Return True
            ElseIf stringValue.ToLower.Equals("false") Or stringValue.ToLower.Equals("no") Or stringValue.ToLower.Equals("off") Then
                Return False
            End If
        ElseIf IsNumeric(value.GetType) Then
            Return IIf(value <> 0, True, False)
        End If
        Return Nothing
    End Function
    ''' <summary>
    ''' 转为双精度数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toDouble(ByVal value As Object) As Double
        If value.GetType.Equals(GetType(Double)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CDbl(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Double.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为单精度数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toSingle(ByVal value As Object) As Single
        If value.GetType.Equals(GetType(Single)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CSng(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Double.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为短整型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toShort(ByVal value As Object) As Short
        If value.GetType.Equals(GetType(Short)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CShort(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Short.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为无符号短整型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toUShort(ByVal value As Object) As UShort
        If value.GetType.Equals(GetType(UShort)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CUShort(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return UShort.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为整型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toInteger(ByVal value As Object) As Integer
        If value.GetType.Equals(GetType(Integer)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CInt(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Integer.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为无符号整型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toUInteger(ByVal value As Object) As UInteger
        If value.GetType.Equals(GetType(UInteger)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CUInt(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return UInteger.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为长整型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toLong(ByVal value As Object) As Long
        If value.GetType.Equals(GetType(Long)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CLng(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Long.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为无符号长整型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toULong(ByVal value As Object) As ULong
        If value.GetType.Equals(GetType(ULong)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CULng(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return ULong.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为字节型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toByte(ByVal value As Object) As Byte
        If value.GetType.Equals(GetType(Byte)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CByte(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Byte.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为无符号字节型数字
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toSByte(ByVal value As Object) As SByte
        If value.GetType.Equals(GetType(SByte)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CSByte(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return SByte.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为字符型
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toChar(ByVal value As Object) As Char
        If value.GetType.Equals(GetType(SByte)) Then
            Return value
        ElseIf IsNumeric(value.GetType) Then
            Return CChar(value)
        ElseIf value.GetType.Equals(GetType(String)) Then
            Return Char.Parse(value)
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 转为字符串
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overloads Shared Function toString(ByVal value As Object) As String
        If Not IsNothing(value) Then
            If value.GetType.Equals(GetType(String)) Then
                Return value
            Else
                Return value.ToString()
            End If
        Else
            Return Nothing
        End If
    End Function

    Public Shared Function typeMismatch(ByVal indexOrName As Object, ByVal actual As Object, ByVal requiredType As String) As Exception
        If IsNumeric(actual) Then
            Throw New Exception("Value at " + indexOrName + " is null.")
        Else
            Throw New Exception("Value " + actual + " at " + indexOrName + " of type " + actual.getClass().getName() + " cannot be converted to " + requiredType)
        End If
    End Function
    Public Shared Function typeMismatch(ByVal actual As Object, ByVal requiredType As String) As Exception
        If IsNumeric(actual) Then
            Throw New Exception("Value is null.")
        Else
            Throw New Exception("Value " + actual + " of type " + actual.getClass().getName() + " cannot be converted to " + requiredType)
        End If
    End Function

    ''' <summary>
    ''' 类型是数字类型
    ''' </summary>
    ''' <param name="dataType">类型</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function IsNumeric(ByVal dataType As Type) As Boolean
        If Microsoft.VisualBasic.IsNothing(dataType) Then
            Return False
        Else
            Return dataType.Equals(GetType(Byte)) Or dataType.Equals(GetType(SByte)) Or dataType.Equals(GetType(Char)) Or _
                   dataType.Equals(GetType(Short)) Or dataType.Equals(GetType(UShort)) Or dataType.Equals(GetType(Integer)) Or _
                   dataType.Equals(GetType(UInteger)) Or dataType.Equals(GetType(Long)) Or dataType.Equals(GetType(ULong)) Or _
                   dataType.Equals(GetType(Single)) Or dataType.Equals(GetType(Double)) Or dataType.Equals(GetType(Int16)) Or _
                   dataType.Equals(GetType(Int32)) Or dataType.Equals(GetType(Int64)) Or dataType.Equals(GetType(UInt16)) Or _
                   dataType.Equals(GetType(UInt32)) Or dataType.Equals(GetType(UInt64)) Or dataType.Equals(GetType(UIntPtr))
        End If
    End Function
End Class
